package chapter4.homework;

import java.util.stream.IntStream;

/**
 * @Project ：learn_java
 * @File ：Q4.java
 * @IDE ：IntelliJ IDEA
 * @Author ：自由如风间
 * @Date ：2025/3/9 19:44
 * @Description ：课后题4
 * 要求创建一个Java程序，启动两个子线程：
 *
 * 一个线程打印1-10之间的奇数（即1, 3, 5, 7, 9）。
 * 另一个线程打印1-10之间的偶数（即2, 4, 6, 8, 10）。
 * 要求：
 * 每个线程要么不打印，要么连续打印5个数，每轮打印之间间隔500毫秒。
 * 两个线程的打印顺序不要求依次交替。
 * 开发提示：
 * 创建资源类PrintNumber，包含变量even（初始为2）、odd（初始为1），以及方法printEven()和printOdd()。
 * 在测试类中创建PrintNumber对象，并启动两个线程分别调用上述方法。
 *
 *
 * 我的评价：
 *      题目的要求很奇怪，首先是让两个线程居然不能交替打印，一般不都是让两个线程交替打印吗？
 *      考上锁的问题，
 *      不然的话用多线程干什么，直接用普通方法不就行了。
 *      这样按序执行线程就只能使用join了，但这又属于是课程之外的知识，
 *      不知道是怎么出题的。。。
 */

public class Q4 {
    public static void main(String[] args) {
        PrintNumber p = new PrintNumber();

        EvenThread evenThread = new EvenThread("偶数线程", p);
        evenThread.start();

        OddThread oddThread = new OddThread("奇数线程", p);

        // 只有使用join方法才可以实现不交替打印，
        // 即一个线程执行完才执行另一个
        // 其他的方法都是实现交替打印的，
        // 这就是题目的奇怪所在，
        // 出这个课程之外的知识完全就是为了出题而出题
        // 完全没有考虑到多线程设计的初衷
        try {
            evenThread.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        oddThread.start();
    }
}

class PrintNumber {
    private int even = 2;

    private int odd = 1;

    public void printEven() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "本轮打印的第" + (i + 1) + "个数字：" + even);
            // Thread.sleep(500);
            even += 2;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public void printOdd() throws InterruptedException {
        // Thread.sleep(500);
        IntStream.range(0, 5).forEach(i -> {
            System.out.println(Thread.currentThread().getName() + "本轮打印的第" + (i + 1) + "个数字：" + odd);
            odd += 2;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }
}

class EvenThread extends Thread {
    private PrintNumber printNumber;

    public EvenThread(String name, PrintNumber printNumber) {
        super(name);
        this.printNumber = printNumber;
    }

    @Override
    public void run() {
        try {
            printNumber.printEven();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

class OddThread extends Thread {
    private PrintNumber printNumber;

    public OddThread(String name, PrintNumber printNumber) {
        super(name);
        this.printNumber = printNumber;
    }

    @Override
    public void run() {
        try {
            printNumber.printOdd();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
